//#import "HTTPFileResponse.h"
//#import "HTTPConnection.h"
//#import "HTTPLogging.h"
//
//#import <unistd.h>
//#import <fcntl.h>
//
//#if ! __has_feature(objc_arc)
//#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
//#endif
//
//// Log levels : off, error, warn, info, verbose
//// Other flags: trace
//static const int httpLogLevel = HTTP_LOG_LEVEL_WARN; // | HTTP_LOG_FLAG_TRACE;
//
//#define NULL_FD  -1
//
//
//@implementation HTTPFileResponse
//
//- (id)initWithFilePath:(NSString *)fpath forConnection:(HTTPConnection *)parent
//{
//	if((self = [super init]))
//	{
//		HTTPLogTrace();
//		
//		connection = parent; // Parents retain children, children do NOT retain parents
//		
//		fileFD = NULL_FD;
//		filePath = [[fpath copy] stringByResolvingSymlinksInPath];
//		if (filePath == nil)
//		{
//			HTTPLogWarn(@"%@: Init failed - Nil filePath", THIS_FILE);
//			
//			return nil;
//		}
//		
//		NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
//		if (fileAttributes == nil)
//		{
//			HTTPLogWarn(@"%@: Init failed - Unable to get file attributes. filePath: %@", THIS_FILE, filePath);
//			
//			return nil;
//		}
//		
//		fileLength = (UInt64)[[fileAttributes objectForKey:NSFileSize] unsignedLongLongValue];
//		fileOffset = 0;
//		
//		aborted = NO;
//		
//		// We don't bother opening the file here.
//		// If this is a HEAD request we only need to know the fileLength.
//	}
//	return self;
//}
//
//- (void)abort
//{
//	HTTPLogTrace();
//	
//	[connection responseDidAbort:self];
//	aborted = YES;
//}
//
//- (BOOL)openFile
//{
//	HTTPLogTrace();
//	
//	fileFD = open([filePath UTF8String], O_RDONLY);
//	if (fileFD == NULL_FD)
//	{
//		HTTPLogError(@"%@[%p]: Unable to open file. filePath: %@", THIS_FILE, self, filePath);
//		
//		[self abort];
//		return NO;
//	}
//	
//	HTTPLogVerbose(@"%@[%p]: Open fd[%i] -> %@", THIS_FILE, self, fileFD, filePath);
//	
//	return YES;
//}
//
//- (BOOL)openFileIfNeeded
//{
//	if (aborted)
//	{
//		// The file operation has been aborted.
//		// This could be because we failed to open the file,
//		// or the reading process failed.
//		return NO;
//	}
//	
//	if (fileFD != NULL_FD)
//	{
//		// File has already been opened.
//		return YES;
//	}
//	
//	return [self openFile];
//}
//
//- (UInt64)contentLength
//{
//	HTTPLogTrace();
//	
//	return fileLength;
//}
//
//- (UInt64)offset
//{
//	HTTPLogTrace();
//	
//	return fileOffset;
//}
//
//- (void)setOffset:(UInt64)offset
//{
//	HTTPLogTrace2(@"%@[%p]: setOffset:%llu", THIS_FILE, self, offset);
//	
//	if (![self openFileIfNeeded])
//	{
//		// File opening failed,
//		// or response has been aborted due to another error.
//		return;
//	}
//	
//	fileOffset = offset;
//	
//	off_t result = lseek(fileFD, (off_t)offset, SEEK_SET);
//	if (result == -1)
//	{
//		HTTPLogError(@"%@[%p]: lseek failed - errno(%i) filePath(%@)", THIS_FILE, self, errno, filePath);
//		
//		[self abort];
//	}
//}
//
//- (NSData *)readDataOfLength:(NSUInteger)length
//{
//	HTTPLogTrace2(@"%@[%p]: readDataOfLength:%lu", THIS_FILE, self, (unsigned long)length);
//	
//	if (![self openFileIfNeeded])
//	{
//		// File opening failed,
//		// or response has been aborted due to another error.
//		return nil;
//	}
//	
//	// Determine how much data we should read.
//	// 
//	// It is OK if we ask to read more bytes than exist in the file.
//	// It is NOT OK to over-allocate the buffer.
//	
//	UInt64 bytesLeftInFile = fileLength - fileOffset;
//	
//	NSUInteger bytesToRead = (NSUInteger)MIN(length, bytesLeftInFile);
//	
//	// Make sure buffer is big enough for read request.
//	// Do not over-allocate.
//	
//	if (buffer == NULL || bufferSize < bytesToRead)
//	{
//		bufferSize = bytesToRead;
//		buffer = reallocf(buffer, (size_t)bufferSize);
//		
//		if (buffer == NULL)
//		{
//			HTTPLogError(@"%@[%p]: Unable to allocate buffer", THIS_FILE, self);
//			
//			[self abort];
//			return nil;
//		}
//	}
//	
//	// Perform the read
//	
//	HTTPLogVerbose(@"%@[%p]: Attempting to read %lu bytes from file", THIS_FILE, self, (unsigned long)bytesToRead);
//	
//	ssize_t result = read(fileFD, buffer, bytesToRead);
//	
//	// Check the results
//	
//	if (result < 0)
//	{
//		HTTPLogError(@"%@: Error(%i) reading file(%@)", THIS_FILE, errno, filePath);
//		
//		[self abort];
//		return nil;
//	}
//	else if (result == 0)
//	{
//		HTTPLogError(@"%@: Read EOF on file(%@)", THIS_FILE, filePath);
//		
//		[self abort];
//		return nil;
//	}
//	else // (result > 0)
//	{
//		HTTPLogVerbose(@"%@[%p]: Read %ld bytes from file", THIS_FILE, self, (long)result);
//		
//		fileOffset += result;
//		
//		return [NSData dataWithBytes:buffer length:result];
//	}
//}
//
//- (BOOL)isDone
//{
//	BOOL result = (fileOffset == fileLength);
//	
//	HTTPLogTrace2(@"%@[%p]: isDone - %@", THIS_FILE, self, (result ? @"YES" : @"NO"));
//	
//	return result;
//}
//
//- (NSString *)filePath
//{
//	return filePath;
//}
//
//- (void)dealloc
//{
//	HTTPLogTrace();
//	
//	if (fileFD != NULL_FD)
//	{
//		HTTPLogVerbose(@"%@[%p]: Close fd[%i]", THIS_FILE, self, fileFD);
//		
//		close(fileFD);
//	}
//	
//	if (buffer)
//		free(buffer);
//	
//}
//
//@end
